home *** CD-ROM | disk | FTP | other *** search
- /* TTY input line editing
- * Copyright 1991 Phil Karn, KA9Q
- * split screen by G. J. van der Grinten, PA0GRI
- * fixed split screen ^B and ^W functions - KO4KS
- */
- #ifdef MSDOS
- #include <conio.h>
- #endif
- #include "global.h"
- #include "ctype.h"
- #include "mbuf.h"
- #include "session.h"
- #include "tty.h"
-
- #if !defined(_lint)
- static char rcsid[] OPTIONAL = "$Id: ttydriv.c,v 1.16 1997/09/14 14:37:46 root Exp root $";
- #endif
-
- #ifdef TNOS_68K
- extern short UseCurses;
- #endif
-
- #define OFF 0
- #define ON 1
-
- #ifndef CTLR
- #define CTLR 18 /* reprint current line */
- #define CTLU 21 /* delete current line in total */
- #define CTLW 23 /* erase last word including preceding space */
- #define CTLZ 26 /* EOF char in dos */
- #define CTLB 02 /* use as F3 in dos but no editing */
- #endif
-
- extern unsigned char SCREENwidth, SCREENlength;
-
- #ifdef ALLSERV
-
- static void backspace (void);
- static void space (void);
- static void switchattr (void);
- static void tochatline (struct session * sp, int gothere);
- static void fromchatline (struct session * sp);
- void clrchatline (struct session * sp);
-
- static int Lastsize = 1;
- static char Lastline[LINESIZE + 1] = "\n";
-
-
- static void
- backspace ()
- {
- int x;
-
- x = wherex ();
- #ifdef TNOS_68K
- if (!x && UseCurses)
- #else
- if (x == 1)
- #endif
- gotoxy (SCREENwidth, wherey () - 1);
- else {
- #ifdef TNOS_68K
- if (UseCurses)
- gotoxy (x - 1, wherey ());
- else
- #endif
- cputs ("\b");
- }
- }
-
-
- static void
- space ()
- {
- cputs (" ");
- }
-
-
- static void
- switchattr ()
- {
- #if !defined(TNOS_68K) && !defined(UNIX)
- struct text_info tr;
- unsigned char attr;
-
- gettextinfo (&tr);
- attr = ((tr.attribute & 0x0f) << 4) + ((tr.attribute & 0x70) >> 4);
- textattr (attr);
- #endif
- #ifdef UNIX
- normvideo ();
- #endif
- }
-
-
- static void
- tochatline (sp, gothere)
- struct session *sp;
- int gothere;
- {
- #ifndef TNOS_68K
- sp->tsavex = wherex ();
- sp->tsavey = wherey ();
- window (1, SCREENlength - 1, SCREENwidth, SCREENlength);
- switchattr ();
- if (gothere)
- gotoxy (sp->bsavex, sp->bsavey);
- #else
- if (UseCurses)
- sp->screen->win = sp->screen->splitwin;
- #endif
- }
-
-
- static void
- fromchatline (sp)
- struct session *sp;
- {
- #ifdef TNOS_68K
- if (UseCurses)
- #endif
- {
- cputs ("_");
- backspace ();
- #ifdef TNOS_68K
- sp->screen->win = sp->screen->textwin;
- #else
- }
- sp->bsavex = wherex ();
- sp->bsavey = wherey ();
- window (1, 1 + sp->screen->statline, SCREENwidth, SCREENlength - 2);
- switchattr ();
- gotoxy (sp->tsavex, sp->tsavey);
- #endif
- }
-
-
- void
- clrchatline (sp)
- struct session *sp;
- {
- tochatline (sp, 0);
- #ifdef TNOS_68K
- if (UseCurses) {
- werase (sp->screen->win);
- gotoxy (0, 0);
- }
- #else
- clrscr ();
- #endif
- fromchatline (sp);
- }
-
-
- /* Accept characters from the incoming tty buffer and process them
- * (if in cooked mode) or just pass them directly (if in raw mode).
- *
- * Echoing (if enabled) is direct to the raw terminal. This requires
- * recording (if enabled) of locally typed info to be done by the session
- * itself so that edited output instead of raw input is recorded.
- * Control-W added by g1emm again.... for word delete.
- * Control-B/Function key 3 added by g1emm for line repeat.
- */
-
- struct mbuf *
- ttydriv (sp, c)
- struct session *sp;
- int c;
- {
- struct mbuf *bp;
- char *cp, *rp;
- int cnt;
-
- switch (sp->ttystate.edit) {
- case OFF:
- bp = ambufw (1);
- *bp->data = uchar (c);
- bp->cnt = 1;
- if (sp->ttystate.echo) {
- if (sp->split) {
- tochatline (sp, 1);
- #if defined(TNOS_68K) || defined(UNIX)
- putch (c);
- #else
- cprintf ("%c", c);
- #endif
- fromchatline (sp);
- } else {
- #if defined(TNOS_68K) || defined(UNIX)
- putch (c);
- #else
- cprintf ("%c", c);
- #endif
- }
- }
- #ifdef TNOS_68K
- rflush ();
- #endif
- return bp;
- case ON:
- if (sp->ttystate.line == NULLBUF)
- sp->ttystate.line = ambufw (LINESIZE);
-
- bp = sp->ttystate.line;
- cp = (char *) (bp->data + bp->cnt);
- /* Perform cooked-mode line editing */
- /* Allow for international character sets - WG7J */
- switch (c) {
- case '\r': /* CR and LF both terminate the line */
- #ifdef TNOS_68K
- case '\l': /* CR and LF both terminate the line */
- #else
- case '\n':
- #endif
- if (sp->ttystate.crnl)
- *cp = '\n';
- else
- *cp = (char) c;
- if (sp->ttystate.echo) {
- if (sp->split) {
- #ifdef TNOS_68K
- if (UseCurses) {
- #endif
- highvideo ();
- rp = (char *) bp->data;
- while (rp < cp)
- #if defined(TNOS_68K) || defined(UNIX)
- putch (*rp++);
- #else
- cprintf ("%c", *rp++);
- #endif
- #ifdef UNIX
- normvideo ();
- #else
- lowvideo ();
- #endif
- clreol ();
- #ifdef TNOS_68K
- }
- #endif
- cputs (Eol);
- clreol ();
- clrchatline (sp);
- } else {
- #if defined(TNOS_68K) || defined(UNIX)
- cputs (Eol);
- #else
- cputs (Eol);
- #endif
- }
- }
- bp->cnt += 1;
- sp->ttystate.line = NULLBUF;
- Lastsize = bp->cnt;
- memcpy (Lastline, bp->data, (size_t) Lastsize);
- return bp;
- case DEL:
- case '\b': /* Character delete */
- if (bp->cnt != 0) {
- bp->cnt--;
- if (sp->ttystate.echo) {
- if (sp->split) {
- tochatline (sp, 1);
- space ();
- backspace ();
- backspace ();
- fromchatline (sp);
- } else {
- backspace ();
- space ();
- backspace ();
- }
- }
- }
- break;
- case CTLR: /* print line buffer */
- if (sp->ttystate.echo) {
- if (sp->split) {
- tochatline (sp, 1);
- #ifdef TNOS_68K
- if (UseCurses)
- werase (sp->screen->win);
- #else
- clrscr ();
- #endif
- rp = (char *) bp->data;
- while (rp < cp)
- #if defined(TNOS_68K) || defined(UNIX)
- putch (*rp++);
- #else
- cprintf ("%c", *rp++);
- #endif
- fromchatline (sp);
- } else {
- #ifdef UNIX
- cputs ("^R");
- cputs (Eol);
- rp = (char *) bp->data;
- while (rp < cp)
- #if defined(TNOS_68K) || defined(UNIX)
- putch (*rp++);
- #else
- cprintf ("%c", *rp++);
- #endif
- #else
- #ifdef TNOS_68K
- cnt = bp->cnt;
- while (cnt != 0) {
- cnt--;
- if (sp->ttystate.echo) {
- backspace ();
- space ();
- backspace ();
- }
- }
- #else
- #if defined(UNIX)
- fprintf (Rawterm, "^R%s", Eol);
- #else
- cprintf ("^R%s", Eol);
- #endif
- #endif
- rp = (char *) bp->data;
- while (rp < cp)
- #if defined(TNOS_68K) || defined(UNIX)
- putch (*rp++);
- #else
- cprintf ("%c", *rp++);
- #endif
- #endif
- }
- }
- break;
- case CTLU: /* Line kill */
- if (sp->split) {
- clrchatline (sp);
- bp->cnt = 0;
- } else {
- while (bp->cnt != 0) {
- bp->cnt--;
- if (sp->ttystate.echo) {
- backspace ();
- space ();
- backspace ();
- }
- }
- }
- break;
- case CTLB: /* Use last line to finish current */
- if (!sp->split) {
- cnt = bp->cnt; /* save count so far */
-
- while (bp->cnt != 0) {
- bp->cnt--;
- if (sp->ttystate.echo) {
- backspace ();
- space ();
- backspace ();
- }
- }
- bp->cnt = (int16) cnt;
- }
- if (bp->cnt < (Lastsize - 1)) {
- memcpy (bp->data + bp->cnt, &Lastline[bp->cnt], (size_t) (Lastsize - 1) - bp->cnt);
- bp->cnt = (int16) Lastsize - 1;
- }
- *(bp->data + bp->cnt) = '\0'; /* make it a string */
- if (sp->ttystate.echo)
- if (sp->split) {
- tochatline (sp, 1); /* was 0 */
- #ifdef TNOS_68K
- if (UseCurses)
- werase (sp->screen->win);
- #else
- clrscr ();
- #endif
- cputs ((char *) bp->data);
- fromchatline (sp);
- } else
- #if defined(TNOS_68K) || defined(UNIX)
- cputs ((char *) bp->data);
- #else
- cputs ((char *) bp->data);
- #endif
- break;
- case CTLW: /* erase word */
- if (sp->split)
- if (sp->ttystate.echo) {
- tochatline (sp, 1);
- space ();
- backspace ();
- }
- cnt = 0; /* we haven't seen a printable char yet */
- while (bp->cnt != 0) {
- *(bp->data + bp->cnt--) = '\n';
- if (sp->ttystate.echo)
- if (sp->split) {
- backspace ();
- space ();
- backspace ();
- } else {
- backspace ();
- space ();
- backspace ();
- }
- if (isspace ((int) *(bp->data + bp->cnt))) {
- if (cnt)
- break;
- } else {
- cnt = 1;
- }
- }
- if (sp->split && sp->ttystate.echo)
- fromchatline (sp);
- break;
- case UPARROW: /* Recall previous command - WG7J */
- case DNARROW: /* Recall next command - WG7J */
- if (Histry) {
- /* Blank out what's already there */
- while (bp->cnt != 0 && sp->ttystate.echo) {
- bp->cnt--;
- cputs ("\b \b");
- }
- if (c == DNARROW)
- /* Adjust history */
- Histry = Histry->next;
- /* Recall last command */
- strcpy ((char *) bp->data, Histry->cmd);
- bp->cnt = (int16) strlen (Histry->cmd);
- if (c == UPARROW)
- /* Adjust history */
- Histry = Histry->prev;
- /* repaint line */
- if (sp->ttystate.echo)
- cputs ((char *) bp->data);
- }
- break;
- default: /* Ordinary character */
- *cp = (char) c;
- bp->cnt++;
-
- /* ^Z apparently hangs the terminal emulators under
- * DoubleDos and Desqview. I REALLY HATE having to patch
- * around other people's bugs like this!!!
- */
- if (sp->ttystate.echo &&
- c != CTLZ &&
- bp->cnt < LINESIZE - 1) {
- if (sp->split) {
- tochatline (sp, 1);
- #if defined(TNOS_68K) || defined(UNIX)
- putch (c);
- #else
- cprintf ("%c", c);
- #endif
- fromchatline (sp);
- } else {
- #if defined(TNOS_68K) || defined(UNIX)
- putch (c);
- #else
- cprintf ("%c", c);
- #endif
- }
-
- } else if (bp->cnt >= LINESIZE - 1) {
- #if defined(TNOS_68K)
- putch ('\007'); /* Beep */
- #else
- #ifdef UNIX
- write (1, "\007", 1);
- #else
- cputs ("\007"); /* Beep */
- #endif
- #endif
- bp->cnt--;
- }
- break;
- }
- break;
- default:
- break;
- }
- #ifdef TNOS_68K
- rflush ();
- #endif
- return NULLBUF;
- }
-
- #else
-
-
- /* Accept characters from the incoming tty buffer and process them
- * (if in cooked mode) or just pass them directly (if in raw mode).
- *
- * Echoing (if enabled) is direct to the raw terminal. This requires
- * recording (if enabled) of locally typed info to be done by the session
- * itself so that edited output instead of raw input is recorded.
- */
- struct mbuf *
- ttydriv (sp, c)
- struct session *sp;
- int c;
- {
- struct mbuf *bp;
- char *cp, *rp;
-
- switch (sp->ttystate.edit) {
- case OFF:
- bp = ambufw (1);
- *bp->data = c;
- bp->cnt = 1;
- if (sp->ttystate.echo)
- #if defined(TNOS_68K) || defined(UNIX)
- putch (c);
- #else
- putc (c, Rawterm);
- #endif
- return bp;
- case ON:
- if (sp->ttystate.line == NULLBUF)
- sp->ttystate.line = ambufw (LINESIZE);
-
- bp = sp->ttystate.line;
- cp = bp->data + bp->cnt;
- /* Allow for international character sets - WG7J */
- /* Perform cooked-mode line editing */
- /* switch(c & 0x7f){ */
- switch (c) {
- case '\r': /* CR and LF both terminate the line */
- case '\n':
- if (sp->ttystate.crnl)
- *cp = '\n';
- else
- *cp = c;
- if (sp->ttystate.echo)
- #if defined(TNOS_68K) || defined(UNIX)
- cputs (Eol);
- #else
- fputs (Eol, Rawterm);
- #endif
-
- bp->cnt += 1;
- sp->ttystate.line = NULLBUF;
- return bp;
- case DEL:
- case '\b': /* Character delete */
- if (bp->cnt != 0) {
- bp->cnt--;
- if (sp->ttystate.echo)
- #if defined(TNOS_68K) || defined(UNIX)
- cputs ("\b \b");
- #else
- fputs ("\b \b", Rawterm);
- #endif
- }
- break;
- case CTLR: /* print line buffer */
- if (sp->ttystate.echo) {
- #if defined(TNOS_68K) || defined(UNIX)
- cputs ("^R");
- cputs (Eol);
- rp = bp->data;
- while (rp < cp)
- putch (*rp++);
- #else
- fprintf (Rawterm, "^R%s", Eol);
- rp = bp->data;
- while (rp < cp)
- putc (*rp++, Rawterm);
- #endif
- }
- break;
- case CTLU: /* Line kill */
- while (bp->cnt != 0) {
- bp->cnt--;
- if (sp->ttystate.echo) {
- #if defined(TNOS_68K) || defined(UNIX)
- cputs ("\b \b");
- #else
- fputs ("\b \b", Rawterm);
- #endif
- }
- }
- break;
- case UPARROW: /* Recall previous command - WG7J */
- case DNARROW: /* Recall next command - WG7J */
- if (Histry) {
- /* Blank out what's already there */
- while (bp->cnt != 0 && sp->ttystate.echo) {
- bp->cnt--;
- cputs ("\b \b");
- }
- if (c == DNARROW)
- /* Adjust history */
- Histry = Histry->next;
- /* Recall last command */
- strcpy (bp->data, Histry->cmd);
- bp->cnt = strlen (Histry->cmd);
- if (c == UPARROW)
- /* Adjust history */
- Histry = Histry->prev;
- /* repaint line */
- if (sp->ttystate.echo)
- cputs (bp->data);
- }
- break;
- default: /* Ordinary character */
- *cp = c;
- bp->cnt++;
-
- /* ^Z apparently hangs the terminal emulators under
- * DoubleDos and Desqview. I REALLY HATE having to patch
- * around other people's bugs like this!!!
- */
- if (sp->ttystate.echo &&
- c != CTLZ &&
- bp->cnt < LINESIZE - 1) {
- #if defined(TNOS_68K) || defined(UNIX)
- putch (c);
- #else
- putc (c, Rawterm);
- #endif
-
- } else if (bp->cnt >= LINESIZE - 1) {
- #if defined(TNOS_68K) || defined(UNIX)
- write (1, "\007", 1);
- #else
- putc ('\007', Rawterm); /* Beep */
- #endif
- bp->cnt--;
- }
- break;
- }
- break;
- }
- return NULLBUF;
- }
-
- #endif /*ALLSERV*/
-